#include "task.h"


using namespace lv::sdk;
using namespace easyWebServer;

Task::Task(QMainWindow * mainWindow, QWidget * widgetForDepth, QWidget * widgetForIR, QWidget * widgetForCloudPoint)
    : m_dockIR(widgetForIR)
    , m_dockDepth(widgetForDepth)
    , m_dockCloudPoint(widgetForCloudPoint)
    , QWidget()
{

    connect(this, SIGNAL(renderDataSig(int)), mainWindow, SLOT(renderData(int)));

    m_IR = new Show2D(widgetForIR);
    m_Depth = new Show2D(widgetForDepth);
    m_CloudPoint = new Show3D(widgetForCloudPoint);

}

Task::~Task()
{
    stop();
}

void Task::start()
{
    m_shutDown = false;
    m_thread = std::async(&Task::work, this);
    qDebug() << "start";

}

void Task::stop()
{
    m_shutDown = true;
    m_thread.wait();
    m_shutDown = false;
    qDebug() << "stop";
}

void Task::work()
{

    slt(LvApi).startStream();
    while (!m_shutDown)
    {
        m_mutex.lock();
        if(m_isLocked == true)
        {
            m_mutex.unlock();
            Sleep(1000);
            continue;
        }
        uint8_t renderType = 0;
        if(slt(Json)["Image"]["IR"].asBool())
        {
            m_IR->__setData(std::shared_ptr(std::move(slt(LvApi).getFrameIR())), 0, 200);
            renderType = renderType | R_IR;
        }
        if(slt(Json)["Image"]["Depth"].asBool())
        {
            auto depthData = slt(LvApi).getFrameDepth();
            auto depthDataShare = std::shared_ptr<LvMat>(std::move(depthData));
            m_Depth->__setData(depthDataShare, slt(Json)["Control"]["ColorMapMin"].asInt(), slt(Json)["Control"]["ColorMapMax"].asInt());
            renderType = renderType | R_Depth;
            if(slt(Json)["Image"]["CloudPoint"].asBool())
            {   
                m_CloudPoint->__setData(std::shared_ptr(std::move(slt(LvApi).getPointCloud(depthDataShare))), 0, 0);
                renderType = renderType | R_CloudPoint;
            }
        }
        
        emit renderDataSig(renderType);
        
        if(slt(Json)["Control"]["IsSetFrameRate"].asBool() == true)
        {
            slt(LvApi).stopStream();
            slt(LvApi).setFrameRate(slt(Json)["Control"]["FrameRate"].asInt());
            slt(LvApi).startStream();
            slt(Json)["Control"]["IsSetFrameRate"] = Json(false);
            // if(para.exposureTime != 0) slt(Json)["Control"]["MaxExposureTime"] = para.exposureTime;
        }
        m_mutex.unlock();
    }   
    qDebug() << "workdown";
    slt(LvApi).stopStream();
}

void Task::workForTigger()
{

    uint8_t renderType = 0;
    if(slt(Json)["Image"]["IR"].asBool())
    {
        m_IR->__setData(std::shared_ptr(std::move(slt(LvApi).getFrameIR())), 0, 200);
        renderType = renderType | R_IR;
    }
    if(slt(Json)["Image"]["Depth"].asBool())
    {
        auto depthData = slt(LvApi).getFrameDepth();
        auto depthDataShare = std::shared_ptr<LvMat>(std::move(depthData));
        m_Depth->__setData(depthDataShare, slt(Json)["Control"]["ColorMapMin"].asInt(), slt(Json)["Control"]["ColorMapMax"].asInt());
        renderType = renderType | R_Depth;
        if(slt(Json)["Image"]["CloudPoint"].asBool())
        {   
            m_CloudPoint->__setData(std::shared_ptr(std::move(slt(LvApi).getPointCloud(depthDataShare))), 0, 0);
            renderType = renderType | R_CloudPoint;
        }
    }
    
    emit renderDataSig(renderType);
}

void Task::showWindow(QWidget* obj, bool setShow)
{
    if(setShow == true) obj->show();
    else obj->hide();
}

void Task::__render(uint8_t type)
{


    // qDebug() << type;
    if(type & R_IR)
    {
        m_IR->__render();
        // qDebug() << "execute IR";

    }
    if(type & R_Depth)
    {
        m_Depth->__render();
        // qDebug() << "execute Depth";

    }
    if(type & R_CloudPoint)
    {
        // qDebug() << "execute cloudPoint";
        m_CloudPoint->__render();
    }
}

bool Task::setlock(bool isLock)
{
    if(isLock)
    {
        m_isLocked = true;
        return m_mutex.try_lock();
    }
    else 
    {
        if(m_isLocked == true)
        {
            m_isLocked = false;
            m_mutex.unlock();
        }
    }
    return true;
}

void Task::saveData()
{
    // _mkdir("save");
    std::string path;
    path += slt(Json)["SavePath"].asString() + "/" + std::to_string(time(NULL));
    _mkdir(path.c_str());
    if(slt(Json)["Image"]["IR"].asBool())
    {
        m_IR->__saveData(path);
    }
    if(slt(Json)["Image"]["Depth"].asBool())
    {
        m_Depth->__saveData(path);

    }
    if(slt(Json)["Image"]["CloudPoint"].asBool())
    {
        m_CloudPoint->__saveData(path);
    }
}



